package com.kamengoranchev.musicrecognizer;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;

import org.json.JSONArray;
import org.json.JSONException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import ch.boye.httpclientandroidlib.HttpResponse;
import ch.boye.httpclientandroidlib.ParseException;
import ch.boye.httpclientandroidlib.util.EntityUtils;

import com.google.common.io.Files;

/**
 * Main activity class
 * **/
public class MusicRecognizerActivity extends Activity  implements OnClickListener{


//	private static final String serverURL ="http://192.168.43.249:8080/";
//	private static final String serverURL ="http://127.0.0.1:8080/";
	private static final String serverURL ="http://192.168.1.111:8080/";
	
	private static final String fileNameShort =  "/audiorecordtest.wav";
	
	private static final String LOG_TAG = "MAIN";

	private Button btnRecord;

	private MediaPlayer player;
	
	private MediaRecorder recorder;
	
	// PROBLEM: class does not record any audio into file
	private ExtAudioRecorder extAudioRecorder;
	
	// logic of recording query to wav file 
	private WavRecorder wavRecorder;
	
	

	private String fileName;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.act_main);
	    
	    btnRecord = (Button)findViewById(R.id.btnRecord);
	    btnRecord.setOnClickListener(this);
	    
	    findViewById(R.id.btnPlay).setOnClickListener(this);
	    
	    player = new MediaPlayer();
	    	    
        fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + fileNameShort;

//        fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/audiorecordtest.wav";
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btnRecord:
			if (btnRecord.getText().equals(getResources().getString(R.string.record_start))) {
				// turn button from start into stop
				//				btnRecord.setText(R.string.record_end);
				
//				startRecordingCompressed();
//				startRecordingUncompressed();
				startRecordingWav();
				stopRecordingWav();
			} else {
				btnRecord.setText(R.string.record_start);
//				stopRecordingCompressed();	
//				stopRecordingUnCompressed();
//				stopRecordingWav();
			}
			break;
			
		case R.id.btnPlay:
			startPlaying();
			break;
		}		
	}
/**
 * plays recorded query. this is not well tested with wav
 * */
	private void startPlaying() {
		player = new MediaPlayer();
        try {
            player.setDataSource(fileName);
            player.prepare();
            player.start();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }
	}
	
	@Deprecated
	private void startRecordingCompressed() {
	    recorder = new MediaRecorder();
	    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
	    recorder.setOutputFormat(MediaRecorder.OutputFormat. THREE_GPP);
	    recorder.setOutputFile(fileName);
	    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);	    

	    try {
            recorder.prepare();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
            Log.e(LOG_TAG, e.getMessage());
        }

        recorder.start();
        
        
        
	}
	@Deprecated
	private void stopRecordingCompressed() {		
		recorder.stop();
        recorder.release();
        recorder = null;
        
        new UploadTask().execute();
	}
	
	@Deprecated
	private void startRecordingUncompressed() {

		// set all parameters

		extAudioRecorder = ExtAudioRecorder.getInstanse(false);

		extAudioRecorder.reset(); 
		
		// prepare file name
		extAudioRecorder.setOutputFile(fileName);
		
		// prepare file header
		extAudioRecorder.prepare();

		extAudioRecorder.start();

	}
	
	@Deprecated
	private void stopRecordingUnCompressed() {		
		extAudioRecorder.stop();
		extAudioRecorder.release();
		extAudioRecorder = null;
	    
	    new UploadTask().execute();
	}

	private void startRecordingWav(){
		if (this.wavRecorder == null)
		this.wavRecorder = new WavRecorder();
		
		wavRecorder.beginRecording(fileName);
		
		
	}
	
	
	private void stopRecordingWav(){
	
		wavRecorder.endRecording();
		
		 new UploadTask().execute();
	}


	
	/**
	 * sends recorded query wav file to server using http post
	 * */
	private class UploadTask extends AsyncTask<Void, Void, HttpResponse> {
		@Override
		protected HttpResponse doInBackground(Void... params) {
			File file = new File(fileName);
			performPost(file);
			return null;
		}
		
		@Override
		protected void onPostExecute(HttpResponse response) {
			super.onPostExecute(response);			
			
//			String result = null;
//			try {
//				result = EntityUtils.toString(response.getEntity(), "utf8");
//			} catch (ParseException e) {
//				e.printStackTrace();
//			} catch (IOException e) {
//				e.printStackTrace();
//			} catch (NullPointerException e) {
//				e.printStackTrace();
//			}
//			Log.i(LOG_TAG, "Server said: " + result);
//			
//			String title;
//			if (response != null && response.getStatusLine().getStatusCode() == 200) {
//				title = "Success";
//			} else {
//				title = "Fail";
//			}
//			
//			new AlertDialog.Builder(MusicRecognizerActivity.this)
//				.setTitle(title)
//				.setMessage(result)
//				.setNeutralButton("OK", null)
//				.show();
		}
	}
	
	
	public void performPost(File audioFile) {
	    HttpURLConnection urlc = null;
	    OutputStreamWriter out = null;
	    DataOutputStream dataout = null;
	    BufferedReader in = null;
	    
	    StringBuffer responseBuffer = new StringBuffer();
        
	    try {
	        URL url = new URL(serverURL);
	        urlc = (HttpURLConnection) url.openConnection();
	        urlc.setRequestMethod("POST");
	        urlc.setDoOutput(true);
	        urlc.setDoInput(true);
	        urlc.setUseCaches(false);
	        urlc.setAllowUserInteraction(false);
	        urlc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
	        
	        Files.copy(audioFile, urlc.getOutputStream());
	        
	        int responseCode = urlc.getResponseCode();
	        in = new BufferedReader(new InputStreamReader(urlc.getInputStream()),8096);
	        String response;
	        
	        // write html to System.out for debug
	        while ((response = in.readLine()) != null) {
	        	responseBuffer.append(response);
	        }
	        
	        Log.v(LOG_TAG, responseBuffer.toString());
	        
	        in.close();
	    } catch (ProtocolException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    } finally {
	        if (out != null) {
	            try {
	                out.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	        if (in != null) {
	            try {
	                in.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    
	    
	    String mockupResult = "[{\"songname\":\"Jovano Jovanke\", \"artist\":\"MEGITZA\",\"distance\":\"1.22422\" }, "
        		+ "{\"songname\":\"Gelem Gelem\", \"artist\":\"MEGITZA\",\"distance\":\"0.13322\" }]";
        
        Intent intent = new Intent(this, ResultsActivity.class);
        intent.putExtra(ResultsActivity.EXTRA_RESULTS, responseBuffer.toString());
        startActivity(intent);
	}
	
	
}